module qmoduleq_g;

import std.stdio;
import std.conv:to;

struct g
{
 struct o
 {
  private:
   static int _r = 0;
   static int _c = 0;
   static int _h = 24;
   static int _w = 80;
   static bool _wrap = true;
  public:
   static @property int r()
   {
    return 1+_r;
   }
   static @property int c()
   {
    return 1+_c;
   }
   static @property int h()
   {
    return _h;
   }
   static @property int w()
   {
    return _w;
   }
   static @property bool wrap()
   {
    return _wrap;
   }
   static @property int r(int i)
   {
    return 1+(_r=i);
   }
   static @property int c(int i)
   {
    return 1+(_c=i);
   }
   static @property bool wrap(bool i)
   {
    return _wrap=i;
   }
   static bool g(bool ret=true)
   { // pass ret (for doing ``if(g(n(...))){...}else{...}''
    writef("\033[%s;%sH",to!(string)(r),to!(string)(c));
    return ret;
   }
   static bool n(bool v, bool f, bool ww=wrap)
   {
    if(v)
    {
     if(f)
     { // TT->TBLR e.g. kotonkun
      if(++_r>=_h)
      { // BOC
       _r%=_h; // go to TOC
       if(ww&&++_c<_w) // if there's wordwrap, go to NC, not TOC
       { // wrapping and room to wrap
        return true;
       }
       else
       { // either wordwrap is false or on last col.
        _c%=_w; // rotate to left of screen if too far
        return false;
       }
      }
      else
      { // not EOL
       return true;
      }
     }
     else
     { // TF->TBRL e.g. japanese
      if(++_r>=_h)
      { // BOC
       _r%=_h; // go to TOC
       if(ww&&_c>0)
       { // wrapping and room to wrap
        _c--; // wrap to PC, not TOC
        return true;
       }
       else
       { // either wordwrap is false or on first col.
        if(ww) // if there's wordwrap, go to PC, not TOC
         _c+=_w-1;
        _c%=_w;   // rotate to right of screen if too far
        return false;
       }
      }
      else
      { // not EOL
       return true;
      }
     }
    }
    else
    {
     if(f)
     { // FT->LRTB e.g. latin
      if(++_c>=_w)
      { // EOL
       _c%=_w; // go to BOL
       if(ww&&++_r<_h) // if there's wordwrap, go to NL, not BOL
       { // wrapping and room to wrap
        return true;
       }
       else
       { // either wordwrap is false or on last line.
        _r%=_h; // rotate to top of screen if too far
        return false;
       }
      }
      else
      { // not EOL
       return true;
      }
     }
     else
     { // FF->LRBT e.g. arabic
      if(_c<=0)
      { // BOL
       _c+=_w-1; // go to EOL
       _c%=_w;
       if(ww&&++_r<_h) // if there's wordwrap, go to NL, not BOL
       { // wrapping and room to wrap
        return true;
       }
       else
       { // either wordwrap is false or on last line.
        _r%=_h; // rotate to top of screen if too far
        return false;
       }
      }
      else
      { // not BOL
       _c--; // advance in reverse
       return true;
      }
     }
    }
   }
 };
};

enum SIG
{
 HUP   =  1,
 INT   =  2, // ^C
 QUIT  =  3, // ^\
 KILL  =  9, // unblockable
 USR1  = 10,
 SEGV  = 11, // unused
 USR2  = 12, // less portable than SIG.USR1
 CHLD  = 17, // sent when child process terminates, stops, or resumes
 CONT  = 18, // unused
 STOP  = 19, // unblockable
 TSTP  = 20, // ^Z
 TTIN  = 21, // when try to read from the tty while in the background
 TTOU  = 22, // when try to write to the tty while in the background
 XCPU  = 24, // when the process used all the available CPU, and therefore the OS is about to
             //  send SIGKILL, in order to QUICKLY save the state and clean up
 WINCH = 28, // resize
 SYS   = 31  // bad argument to system call
}

extern(C) void signal(int, void function(int) @system);




